let a = 4 in  (*in后面的语句， 相当于新的语句块*) 
    let a = a + 2 in
        let a = a * 2 in
            printfn "%d" a;;

(fun x -> x * x) 5;;    (*函数*)


let x = 38 in x + 4;;   (*局部变量绑定*)


let x = 52;;            (*全局变量绑定*)

(*初始空环境 {} *) 
let a = 5 in
    (* b x 的定义环境{a->5} *)
    let b x = a + x in (*函数b*)
        let a = 42 in
            b 0;;
(* 将 x->0 添加到定义环境{a->5},在新环境{x->0,a->5}求  a+x的值  *) 

(*扩展环境env {}为 env{a->3}，然后求值 a+2*)
let a = 3 in a + 2;;

(* 定义递归函数 *)
let rec fac n = if n < 2 then 1 else n * fac (n-1);;

(* 间接递归函数 *)
let rec fac n = if n < 2 then 1 else n * fac1 n
    and fac1 n = fac (n - 1);;

 (*List.map对列表的每个元素bn应用函数f以产生另一个列表*)
List.map (fun a -> a + 10) [42; 17; 128];;
//val it : int list = [52; 27; 138]

(*List.fold对列表的元素bn应用函数f以生成一个累积值*)
List.fold (fun s e -> s + e) 0 [42; 17; 128];;
//val it : int = 187

(*List.iter对列表的每个元素应用函数f; 返回unit*)
List.iter (printf "%d") [42; 17; 128];;
//4217128val it : unit = ()
List.iter (printfn "%d") [42; 17; 128];;
//42
//17
//128
//val it : unit = ()

(*模式匹配*)
let xor p = 
    match p with 
    | (false, false) -> false
    | (false, true) -> true
    | ( true, false) -> true
    | ( true, true) -> false;;

(*下划线（_）通配符，匹配任何东西，作为默认值用*)
let xor p = 
    match p with 
    | (true, false) 
    | (false, true) -> true
    | _ -> false;;
(*
> xor (true, false);;        
val it : bool = true

> xor (false, true);;        
val it : bool = true

> xor (false, false);;       
val it : bool = false

*)

(* let length = fun p -> match p with *)
let length = function 
    [] -> "empty"
    | [_] -> "singleton"
    | [_; _] -> "pair"
    | [_; _; _] -> "triplet"
    | hd :: tl -> "many";;

let length = fun p -> 
    match p with 
    [] -> "empty"
    | [_] -> "singleton"
    | [_; _] -> "pair"
    | [_; _; _] -> "triplet"
    | hd :: tl -> "many";;

let length p = 
    match p with 
    [] -> "empty"
    | [_] -> "singleton"
    | [_; _] -> "pair"
    | [_; _; _] -> "triplet"
    | hd :: tl -> "many";;

(*模式匹配与when和as*)
let tall = function
    | (h, s) when h > 180 -> s + " is tall"
    | (_, s) -> s + " is short";;

List.map tall [(183, "Stephen"); (150, "Nina")];;
//val it : string list = ["Stephen is tall"; "Nina is short"]

(*使用as关键字可以命名被匹配结构*)
match ((3,9), 4) with
    (_ as x, 4) -> x
    | _ -> (0,0);;
//val it : int * int = (3, 9)

match ((3,9), 3) with
    | (_ as x, 4) -> x
    | _ -> (0,0);;
//val it : int * int = (0, 0)

type seasons = Winter | Spring | Summer | Fall;;
let weather = function
    Winter -> "Too Cold"
    | Spring -> "Too Wet"
    | Summer -> "Too Hot"
    | Fall -> "Too Short";;
weather Spring;;

type operator = Add | Sub | Mul | Div;;
type expr =
    | Binop of expr * operator * expr
    | Lit of int;;
let rec eval = function
    Lit(x) -> x
    | Binop(e1, op, e2) ->
        let v1 = eval e1 
        let v2 = eval e2 in
            match op with
                | Add -> v1 + v2
                | Sub -> v1 - v2
                | Mul -> v1 * v2
                | Div -> v1 / v2;;
eval(Lit(10));;
//val it : int = 10
eval(Binop(Lit(10), Add, Lit(11)));;
//val it : int = 21